home *** CD-ROM | disk | FTP | other *** search
/ PC PowerPlay 22 / PCPP #22.iso / Quake2 / q2source_12_11 / utils3 / common / scriplib.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-11-18  |  5.1 KB  |  276 lines

  1. // scriplib.c
  2.  
  3. #include "cmdlib.h"
  4. #include "scriplib.h"
  5.  
  6. /*
  7. =============================================================================
  8.  
  9.                         PARSING STUFF
  10.  
  11. =============================================================================
  12. */
  13.  
  14. typedef struct
  15. {
  16.     char    filename[1024];
  17.     char    *buffer,*script_p,*end_p;
  18.     int     line;
  19. } script_t;
  20.  
  21. #define    MAX_INCLUDES    8
  22. script_t    scriptstack[MAX_INCLUDES];
  23. script_t    *script;
  24. int            scriptline;
  25.  
  26. char    token[MAXTOKEN];
  27. qboolean endofscript;
  28. qboolean tokenready;                     // only true if UnGetToken was just called
  29.  
  30. /*
  31. ==============
  32. AddScriptToStack
  33. ==============
  34. */
  35. void AddScriptToStack (char *filename)
  36. {
  37.     int            size;
  38.  
  39.     script++;
  40.     if (script == &scriptstack[MAX_INCLUDES])
  41.         Error ("script file exceeded MAX_INCLUDES");
  42.     strcpy (script->filename, ExpandPath (filename) );
  43.  
  44.     size = LoadFile (script->filename, (void **)&script->buffer);
  45.  
  46.     printf ("entering %s\n", script->filename);
  47.  
  48.     script->line = 1;
  49.  
  50.     script->script_p = script->buffer;
  51.     script->end_p = script->buffer + size;
  52. }
  53.  
  54.  
  55. /*
  56. ==============
  57. LoadScriptFile
  58. ==============
  59. */
  60. void LoadScriptFile (char *filename)
  61. {
  62.     script = scriptstack;
  63.     AddScriptToStack (filename);
  64.  
  65.     endofscript = false;
  66.     tokenready = false;
  67. }
  68.  
  69.  
  70. /*
  71. ==============
  72. ParseFromMemory
  73. ==============
  74. */
  75. void ParseFromMemory (char *buffer, int size)
  76. {
  77.     script = scriptstack;
  78.     script++;
  79.     if (script == &scriptstack[MAX_INCLUDES])
  80.         Error ("script file exceeded MAX_INCLUDES");
  81.     strcpy (script->filename, "memory buffer" );
  82.  
  83.     script->buffer = buffer;
  84.     script->line = 1;
  85.     script->script_p = script->buffer;
  86.     script->end_p = script->buffer + size;
  87.  
  88.     endofscript = false;
  89.     tokenready = false;
  90. }
  91.  
  92.  
  93. /*
  94. ==============
  95. UnGetToken
  96.  
  97. Signals that the current token was not used, and should be reported
  98. for the next GetToken.  Note that
  99.  
  100. GetToken (true);
  101. UnGetToken ();
  102. GetToken (false);
  103.  
  104. could cross a line boundary.
  105. ==============
  106. */
  107. void UnGetToken (void)
  108. {
  109.     tokenready = true;
  110. }
  111.  
  112.  
  113. qboolean EndOfScript (qboolean crossline)
  114. {
  115.     if (!crossline)
  116.         Error ("Line %i is incomplete\n",scriptline);
  117.  
  118.     if (!strcmp (script->filename, "memory buffer"))
  119.     {
  120.         endofscript = true;
  121.         return false;
  122.     }
  123.  
  124.     free (script->buffer);
  125.     if (script == scriptstack+1)
  126.     {
  127.         endofscript = true;
  128.         return false;
  129.     }
  130.     script--;
  131.     scriptline = script->line;
  132.     printf ("returning to %s\n", script->filename);
  133.     return GetToken (crossline);
  134. }
  135.  
  136. /*
  137. ==============
  138. GetToken
  139. ==============
  140. */
  141. qboolean GetToken (qboolean crossline)
  142. {
  143.     char    *token_p;
  144.  
  145.     if (tokenready)                         // is a token allready waiting?
  146.     {
  147.         tokenready = false;
  148.         return true;
  149.     }
  150.  
  151.     if (script->script_p >= script->end_p)
  152.         return EndOfScript (crossline);
  153.  
  154. //
  155. // skip space
  156. //
  157. skipspace:
  158.     while (*script->script_p <= 32)
  159.     {
  160.         if (script->script_p >= script->end_p)
  161.             return EndOfScript (crossline);
  162.         if (*script->script_p++ == '\n')
  163.         {
  164.             if (!crossline)
  165.                 Error ("Line %i is incomplete\n",scriptline);
  166.             scriptline = script->line++;
  167.         }
  168.     }
  169.  
  170.     if (script->script_p >= script->end_p)
  171.         return EndOfScript (crossline);
  172.  
  173.     // ; # // comments
  174.     if (*script->script_p == ';' || *script->script_p == '#'
  175.         || ( script->script_p[0] == '/' && script->script_p[1] == '/') )
  176.     {
  177.         if (!crossline)
  178.             Error ("Line %i is incomplete\n",scriptline);
  179.         while (*script->script_p++ != '\n')
  180.             if (script->script_p >= script->end_p)
  181.                 return EndOfScript (crossline);
  182.         goto skipspace;
  183.     }
  184.  
  185.     // /* */ comments
  186.     if (script->script_p[0] == '/' && script->script_p[1] == '*')
  187.     {
  188.         if (!crossline)
  189.             Error ("Line %i is incomplete\n",scriptline);
  190.         script->script_p+=2;
  191.         while (script->script_p[0] != '*' && script->script_p[1] != '/')
  192.         {
  193.             script->script_p++;
  194.             if (script->script_p >= script->end_p)
  195.                 return EndOfScript (crossline);
  196.         }
  197.         script->script_p += 2;
  198.         goto skipspace;
  199.     }
  200.  
  201. //
  202. // copy token
  203. //
  204.     token_p = token;
  205.  
  206.     if (*script->script_p == '"')
  207.     {
  208.         // quoted token
  209.         script->script_p++;
  210.         while (*script->script_p != '"')
  211.         {
  212.             *token_p++ = *script->script_p++;
  213.             if (script->script_p == script->end_p)
  214.                 break;
  215.             if (token_p == &token[MAXTOKEN])
  216.                 Error ("Token too large on line %i\n",scriptline);
  217.         }
  218.         script->script_p++;
  219.     }
  220.     else    // regular token
  221.     while ( *script->script_p > 32 && *script->script_p != ';')
  222.     {
  223.         *token_p++ = *script->script_p++;
  224.         if (script->script_p == script->end_p)
  225.             break;
  226.         if (token_p == &token[MAXTOKEN])
  227.             Error ("Token too large on line %i\n",scriptline);
  228.     }
  229.  
  230.     *token_p = 0;
  231.  
  232.     if (!strcmp (token, "$include"))
  233.     {
  234.         GetToken (false);
  235.         AddScriptToStack (token);
  236.         return GetToken (crossline);
  237.     }
  238.  
  239.     return true;
  240. }
  241.  
  242.  
  243. /*
  244. ==============
  245. TokenAvailable
  246.  
  247. Returns true if there is another token on the line
  248. ==============
  249. */
  250. qboolean TokenAvailable (void)
  251. {
  252.     char    *search_p;
  253.  
  254.     search_p = script->script_p;
  255.  
  256.     if (search_p >= script->end_p)
  257.         return false;
  258.  
  259.     while ( *search_p <= 32)
  260.     {
  261.         if (*search_p == '\n')
  262.             return false;
  263.         search_p++;
  264.         if (search_p == script->end_p)
  265.             return false;
  266.  
  267.     }
  268.  
  269.     if (*search_p == ';')
  270.         return false;
  271.  
  272.     return true;
  273. }
  274.  
  275.  
  276.